﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenComposite.EII.Forms;
using OpenComposite.EII.Repository;

namespace OpenComposite.EII.RepositoryUIs
{
	public partial class FormCreateNewUser : FormCreateNewBase
	{
		public FormCreateNewUser(User user, bool bAllowContinue)
			: base(user, user, bAllowContinue)
		{
			_user = user;;
			InitializeComponent();

			this.CreateAtToolStrip.Visible = false;

			tscmbOrgUnit.ComboBox.DrawMode = DrawMode.OwnerDrawFixed;
			tscmbOrgUnit.ComboBox.DrawItem += new DrawItemEventHandler(ComboBox_DrawItem);
		}

		private User _user = null;

		private bool save()
		{
			bool cancel = false;
			if ( string.IsNullOrEmpty(txtFirstName.Text) ) {
				txtFirstName.Focus();
				cancel = true;
			} else if ( string.IsNullOrEmpty(txtLastName.Text) ) {
				txtLastName.Focus();
				cancel = true;
			} else if ( string.IsNullOrEmpty(txtPassword.Text) ) {
				txtPassword.Focus();
				cancel = true;
			} else if ( string.IsNullOrEmpty(txtConfirmPassword.Text) ) {
				txtConfirmPassword.Focus();
				cancel = true;
			} else if ( string.IsNullOrEmpty(txtUserID.Text) ) {
				txtUserID.Focus();
				cancel = true;
			}
			if (  cancel ) {
				MessageBox.Show("You need to fill out all marked fields!", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			if ( Global.Data.ExistsOrgUser(txtUserID.Text) ) {
				MessageBox.Show("An User with this user name already exists!", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			if ( txtPassword.Text != txtConfirmPassword.Text ) {
				MessageBox.Show("The password and confirm password fields do not match.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
				txtPassword.Focus();
				txtPassword.SelectAll();
				return false;
			}
			_user.FirstName = txtFirstName.Text;
			_user.LastName = txtLastName.Text;
			_user.Notes = txtNotes.Text;
			_user.UserName = txtUserID.Text;
			_user.Password = txtPassword.Text;
			_user.Save();
			return true;
		}

		protected override void OnSaveClose(CancelEventArgs e)
		{
			if ( save() ) {
				base.OnSaveClose(e);

				// set selected item as new parent item
				_orgdropdownitem item = tscmbOrgUnit.SelectedItem as _orgdropdownitem;
				this.NewParentItem = item.OrgUnit != null ? item.OrgUnit : null;
			}
		}

		protected override void OnSaveContinue(CancelEventArgs e)
		{
			if ( save() ) {
				base.OnSaveContinue(e);
			}
		}
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			tscmbOrgUnit.BeginUpdate();
			try {
				Organization org = Global.Data.GetOrganisationById(Global.CurrentUser.OrganizationID);
				tscmbOrgUnit.Items.Add(new _orgdropdownitem(org));
				foreach ( var ou in org.GetOrgUnits() ) {
					addOrgUnit(ou, 1);
				}
				if ( tscmbOrgUnit.SelectedIndex < 0 ) tscmbOrgUnit.SelectedIndex = 0;
			} finally {
				tscmbOrgUnit.EndUpdate();
			}
		}
		private void addOrgUnit(OrganizationalUnit orgunit, int indent)
		{
			int pos = tscmbOrgUnit.Items.Add(new _orgdropdownitem(orgunit, indent));
			if ( this.ParentItem == orgunit ) tscmbOrgUnit.SelectedIndex = pos;
			foreach ( var ou in orgunit.GetSubOrgUnits() ) {
				addOrgUnit(ou, indent + 1);
			}
		}

		private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
		{
			ComboBox cmb = sender as ComboBox;
			if ( cmb == null ) return;

			e.DrawBackground();
			if ( ( e.State & DrawItemState.Focus ) == DrawItemState.Focus )
				e.DrawFocusRectangle();

			if ( e.Index < 0 || e.Index >= cmb.Items.Count ) {
				using ( StringFormat sf = new StringFormat() ) {
					sf.Trimming = StringTrimming.None;
					sf.Alignment = StringAlignment.Center;
					sf.LineAlignment = StringAlignment.Center;
					string txt = "- Not Available -";
					e.Graphics.DrawString(txt, e.Font, SystemBrushes.GrayText, e.Bounds, sf);
				}
			} else {
				_orgdropdownitem item = cmb.Items[e.Index] as _orgdropdownitem;
				if ( item != null ) {
					int indent = IndentWidth * item.Indent + 2;
					int textGap = 0;

					// draw image
					if ( item.Image != null ) {
						textGap = TextGap;
						Rectangle rectImg = new Rectangle(e.Bounds.X + indent, e.Bounds.Y,
														  TextGap, e.Bounds.Height);
						e.Graphics.DrawImageUnscaled(item.Image, rectImg);
					}
					// draw text
					RectangleF rectText = new RectangleF(e.Bounds.Left + textGap + indent, e.Bounds.Y,
														 e.Bounds.Width - textGap - indent, e.Bounds.Height);
					using ( StringFormat sf = new StringFormat() )
					using ( Brush b = new SolidBrush(e.ForeColor) ) {
						sf.Trimming = StringTrimming.EllipsisCharacter;
						sf.Alignment = StringAlignment.Near;
						sf.LineAlignment = StringAlignment.Center;
						e.Graphics.DrawString(item.Text, e.Font, b, rectText, sf);
					}

				} else {
					using ( StringFormat sf = new StringFormat() )
					using ( Brush b = new SolidBrush(e.ForeColor) ) {
						sf.Trimming = StringTrimming.EllipsisCharacter;
						sf.Alignment = StringAlignment.Near;
						sf.LineAlignment = StringAlignment.Center;
						e.Graphics.DrawString(cmb.Items[e.Index].ToString(), e.Font, b, e.Bounds, sf);
					}
				}
			}
		}

		#region Private Class: _orgdropdownitem
		private class _orgdropdownitem
		{
			private _orgdropdownitem(Organization org, OrganizationalUnit orgunit, int indent)
			{
				this.Org = org;
				this.OrgUnit = orgunit;
				this.Indent = indent;
			}
			public _orgdropdownitem(Organization org)
				: this(org, null, 0)
			{
			}
			public _orgdropdownitem(OrganizationalUnit orgunit, int indent)
				: this(null, orgunit, indent)
			{
			}
			public Organization Org { get; set; }
			public OrganizationalUnit OrgUnit { get; set; }

			public int Indent { get; protected set; }
			public string Text
			{
				get
				{
					if ( this.OrgUnit != null ) {
						return this.OrgUnit.Name;
					} else if ( this.Org != null ) {
						return this.Org.Name;
					} else {
						return "";
					}
				}
			}
			public Image Image
			{
				get {
					if ( this.OrgUnit != null ) {
						return this.OrgUnit.Image;
					} else if ( this.Org != null ) {
						return this.Org.Image;
					} else {
						return null;
					}
				}
			}
		}
		#endregion
	}
}
